package com.guoxue.action.front;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.guoxue.consts.SCUser;
import com.guoxue.dataClasses.SimpleData;
import com.guoxue.domain.UserVo;
import com.guoxue.service.IUserService;
import com.guoxue.util.LoggerUtil;
import com.guoxue.util.MessageSendUtil;
import com.guoxue.util.OtherUtils;
import com.guoxue.util.RedisUtil;
import com.guoxue.util.codeSwitch.zt;

import redis.clients.jedis.Jedis;

@Controller
@RequestMapping("User")
/**
 * 短信发送处理接口 只负责短信接口的调用
 * 
 * @author kanghb
 */
public class SendMessageAction extends BaseAction {
	@Resource
	private IUserService userService;

	public static String getSmsRedisKey(final int uid, final String telNumber, final int opType) {
		// String key = "smsCode:" + opType + ":" + uid + ":" + telNumber;
		// return key;
		if (zt.cs_smsKey重构.isOn()) {
			String key = "smsCode:" + opType + ":" + uid + ":" + telNumber;
			return key;
		}
		return "message" + telNumber;
	}

	/***
	 * 生成需要在redis中缓存的键值(格式:缓存时间(ms) + 分隔符("#:#") + 短信验证码)
	 * 
	 * @param smsCode
	 *            短信验证码
	 * @return
	 */
	public static String generateSmsRedisValue(final String smsCode) {
		String value = System.currentTimeMillis() + "#:#" + smsCode;
		return value;
	}

	/**
	 * 解析redis中缓存的键值
	 * 
	 * @param redisValue
	 * @return SimpleData.count=当前时间(ms)-创建时间(ms)。SimpleData.name=短信验证码。
	 */
	public static SimpleData parseSmsRedisValue(final String redisCodeValue) {
		int index;
		SimpleData result;
		String word;
		long ltime_generate, ltime_delta;

		if (redisCodeValue == null || redisCodeValue.length() <= 0) {
			return null;
		}
		index = redisCodeValue.indexOf("#:#");
		if (index > 0) {
			result = new SimpleData();
			word = redisCodeValue.substring(0, index);
			ltime_generate = Long.parseLong(word);
			ltime_delta = System.currentTimeMillis() - ltime_generate;
			result.count = (int) ltime_delta;
			result.name = redisCodeValue.substring(index + 3);
			return result;
		}
		return null;
	}

	/**
	 * 短信发送接口
	 * 
	 * @param req
	 * @param resp
	 * @param tel
	 * @param type
	 *            1:注册 、2：修改
	 * @return
	 */
	@RequestMapping("/sendMessage")
	@ResponseBody
	public JSON sendMessage(HttpServletRequest req, HttpServletResponse resp, String tel, Integer type) {
		zt.ts.function(); // 待作废!
		Jedis jedis = RedisUtil.getJedis();
		try {
			if (!OtherUtils.isMobileNO(tel)) {
				return Message(ERROR, "请确保手机号码格式正确", null);
			}
			if (!isEmpty(jedis.get("message" + tel))) {
				JSONObject obj = new JSONObject();
				obj.put("messageCode", jedis.get("message" + tel));
				return Message(SUCCESS, "验证码已发送,请耐心等待、验证码时效5分钟", obj);
			}
			if (type != null) {
				if (type == 1) {
					UserVo entity = userService.getUserByTel(tel);// 检测当前手机号是否已注册
					if (entity == null) {
						if (!isEmpty(tel)) {
							JSONObject check = MessageSendUtil.sendMessage(tel, "reg");
							if (check.get("isSuccess").equals("2")) {
								return Message(ERROR, "获取验证码失败,请稍后再试", null);
							} else {
								JSONObject obj = new JSONObject();
								obj.put("messageCode", check.get("radomInt"));
								jedis.setex("message" + tel, 1 * 60, check.get("radomInt").toString());
								return Message(SUCCESS, "验证码5分钟内有效", obj);
							}
						} else {
							return Message(ERROR, BAD_PARAM, null);
						}
					} else {
						return Message(ALREADY_REG, GO_LOGIN, tel);
					}
				} else if (type == 2) {
					UserVo entityB = userService.getUserByTel(tel); // 检测当前手机号是否已注册
					if (entityB != null) {
						JSONObject check = MessageSendUtil.sendMessage(tel, "modify");
						if (check.get("isSuccess").equals("2")) {
							return Message(ERROR, "获取验证码失败,稍后再试", null);
						} else {
							jedis.setex("message" + tel, 5 * 60, check.get("radomInt").toString());
							JSONObject obj = new JSONObject();
							obj.put("headUrl", entityB.getImgUrl());
							obj.put("messageCode", check.get("radomInt"));
							return Message(SUCCESS, "验证码10分钟内有效", obj);
						}
					} else {
						return Message(ERROR, "当前账号未注册", tel);
					}
				} else {
					return Message(ERROR, "未知type类型", type);
				}
			} else {
				return Message(ERROR, BAD_PARAM, null);
			}
		} catch (Exception e) {
			return LoggerUtil.logInfo(e, ERROR);
		} finally {
			jedis.close();
		}
	}

	/**
	 * 短信发送(获取验证码)接口。登录前(获得用户身份前)使用
	 * 
	 * @param req
	 * @param resp
	 * @param tel
	 *            客户端提供的手机号码
	 * @param type
	 *            1:注册(用户准备通过手机号码,注册新账号);
	 * @return
	 */
	@RequestMapping("/sendSmsBeforeLogin")
	@ResponseBody
	public JSON A0_sendSmsBeforeLogin(HttpServletRequest req, HttpServletResponse resp, final String tel,
			final Integer type) {
		final String redisCodeKey, redisCodeValue_old, redisCodeValue_new; // redis键值(缓存验证码)
		final UserVo userVo, userVo_cur;
		// final int uid = SCUser.getUidFromReq(req);
		final SimpleData sd; // 对redis中缓存的键值的解析结果
		JSONObject json;

		// 参数检查:
		// 检查type参数:
		if (type == null || type < 1 || type > 1) {
			return Message(ERROR, "未知type类型", type);
		}
		// 检查手机号码格式:
		zt.tb.function(); // isMobileNO方法中,增加对tel为空的检查
		// if (mobiles == null || mobiles.length() < 8) {
		// return false;
		// }
		if (!OtherUtils.isMobileNO(tel)) {
			return Message(ERROR, "请输入正确的手机号码", null);
		}
		redisCodeKey = SendMessageAction.getSmsRedisKey(-1/* 登录前操作,uid总是-1! */, tel, type);

		// 获取jedis连接:
		final Jedis jedis = RedisUtil.getJedis();
		try {
			// 检查之前存储的验证码:
			redisCodeValue_old = jedis.get(redisCodeKey);
			if (!isEmpty(redisCodeValue_old)) { // 短信验证码已存在
				sd = SendMessageAction.parseSmsRedisValue(redisCodeValue_old);
				if (sd.count < 50 && sd.count > -10) { // 一分钟内重复发送
					// 客户端应有1分钟时间限制,因此一般不会到达此处
					zt.ts.function(); // 短信验证码不能直接发给客户端!
					// json = new JSONObject();
					// json.put("messageCode", sd.name);
					// return Message(SUCCESS, "验证码已发送,请耐心等待。", json);
					return Message(SUCCESS, "验证码已发送,请耐心等待。", null);
				}
			}

			// 针对不同type的检查:
			if (type == 1) { // 注册(用户准备通过手机号码,注册新账号)
				userVo = userService.getUserByTel(tel); // 检查准备绑定的电话号码,是否已被绑定过
				if (userVo != null) {
					return Message(ALREADY_REG, GO_LOGIN, tel);
					// return Message(ERROR, "该手机号码已绑定了其它账号,不能重复绑定", null);
				}
			}

			// 至此,通过了检查,尝试发送短信:
			JSONObject check = MessageSendUtil.sendMessage(tel, "modify");
			if (check.get("isSuccess").equals("2")) {
				return Message(ERROR, "获取验证码失败,稍后再试", null);
			}
			// 将短信验证码缓存到redis(有效时长:10分钟)
			redisCodeValue_new = SendMessageAction.generateSmsRedisValue(check.get("radomInt").toString());
			jedis.setex(redisCodeKey, 10 * 60, redisCodeValue_new);
			zt.ts.function(); // 不应将验证码(以及headUrl?),发送给客户端!
			// JSONObject obj = new JSONObject();
			// obj.put("messageCode", check.get("radomInt"));
			// return Message(SUCCESS, "验证码10分钟内有效", obj);
			return Message(SUCCESS, "验证码10分钟内有效", null);
		} catch (Exception e) {
			return LoggerUtil.logInfo(e, ERROR);
		} finally {
			jedis.close();
		}
	}

	/**
	 * 短信发送(获取验证码)接口。登录后(获得用户身份后)使用
	 * 
	 * @param req
	 * @param resp
	 * @param tel
	 *            客户端提供的手机号码
	 * @param type
	 *            102:用户准备bindTel(绑定电话号码);
	 *            103:用户准备modifyTel(修改绑定的电话号码)(注意此时tel应为旧的(原来绑定的)手机号码!);
	 *            104:用户准备modifyPassword(修改密码))
	 * @return
	 */
	@RequestMapping("/sendSmsAfterLogin")
	@ResponseBody
	public JSON A1_sendSmsAfterLogin(HttpServletRequest req, HttpServletResponse resp, final String tel,
			final Integer type) {
		final String redisCodeKey, redisCodeValue_old, redisCodeValue_new; // redis键值(缓存验证码)
		final UserVo userVo, userVo_cur;
		final int uid = SCUser.getUidFromReq(req);
		final SimpleData sd; // 对redis中缓存的键值的解析结果
		JSONObject json;

		// 参数检查:
		// 检查type参数:
		if (type == null || type < 102 || type > 104) {
			return Message(ERROR, "未知type类型", type);
		}
		// 检查手机号码格式:
		if (!OtherUtils.isMobileNO(tel)) {
			return Message(ERROR, "请输入正确的手机号码", null);
		}
		redisCodeKey = SendMessageAction.getSmsRedisKey(uid, tel, type);

		// 获取jedis连接:
		final Jedis jedis = RedisUtil.getJedis();
		try {
			// 检查之前存储的验证码:
			redisCodeValue_old = jedis.get(redisCodeKey);
			if (!isEmpty(redisCodeValue_old)) { // 短信验证码已存在
				sd = SendMessageAction.parseSmsRedisValue(redisCodeValue_old);
				if (sd.count < 50 && sd.count > -10) { // 一分钟内重复发送
					// 客户端应有1分钟时间限制,因此一般不会到达此处
					zt.ts.function(); // 短信验证码不能直接发给客户端!
					// json = new JSONObject();
					// json.put("messageCode", sd.name);
					// return Message(SUCCESS, "验证码已发送,请耐心等待。", json);
					return Message(SUCCESS, "验证码已发送,请耐心等待。", null);
				}
			}

			// 针对不同type的检查:
			if (type == 102) { // 用户准备bindTel(绑定电话号码)
				zt.tb.optimize(); // 是否需要检查,用户是否已绑定过了手机号码?
				userVo_cur = userService.getUserByKey(uid);
				if (!isEmpty(userVo_cur.getUserTel())) {
					return Message(ERROR, "您已绑定了手机号码", null);
				}
				userVo = userService.getUserByTel(tel); // 检查准备绑定的电话号码,是否已被绑定过了
				if (userVo != null) {
					if (userVo.getId() == uid) {
						return Message(ERROR, "您已绑定了该手机号码,不能重复绑定", null);
					} else {
						return Message(ERROR, "该手机号码已被其它账号绑定了,不能重复绑定", null);
					}
				}
			} else if (type == 103) { // 用户准备modifyTel(修改绑定的电话号码)(注意此时tel应为旧的(原来绑定的)手机号码!);
				userVo_cur = userService.getUserByKey(uid);
				if (isEmpty(userVo_cur.getUserTel()) || tel.equals(userVo_cur.getUserTel()) == false) {
					return Message(ERROR, "手机号码参数错误", null);
				}
				// userVo = userService.getUserByTel(tel); //
				// 检查准备绑定的电话号码,是否已被绑定过了
				// if (userVo != null) {
				// if (userVo.getId() == uid) {
				// return Message(ERROR, "您已绑定了该手机号码,不能重复绑定", null);
				// } else {
				// return Message(ERROR, "该手机号码已绑定了其它账号,不能重复绑定", null);
				// }
				// }
			} else if (type == 104) { // 用户准备modifyPassword(修改密码))
				userVo_cur = userService.getUserByKey(uid);
				if (isEmpty(userVo_cur.getUserTel())) {
					zt.ta.function(); // 是否要求只有绑定了手机号码的账号,才能修改密码?
					return Message(ERROR, "只有绑定了手机号码,才能修改密码", null);
				}
				if (!tel.equals(userVo_cur.getUserTel())) {
					return Message(ERROR, "手机号码参数错误", null);
				}
			}

			// 至此,通过了检查,尝试发送短信:
			zt.ta.function(); // 类MessageSendUtil待整理
			JSONObject check = MessageSendUtil.sendMessage(tel, "modify");
			if (check.get("isSuccess").equals("2")) {
				return Message(ERROR, "获取验证码失败,稍后再试", null);
			}
			// 将短信验证码缓存到redis(有效时长:10分钟)
			redisCodeValue_new = SendMessageAction.generateSmsRedisValue(check.get("radomInt").toString());
			jedis.setex(redisCodeKey, 10 * 60, redisCodeValue_new);
			zt.ts.function(); // 不应将验证码(以及headUrl?),发送给客户端!
			// JSONObject obj = new JSONObject();
			// obj.put("headUrl", userVo.getImgUrl());
			// obj.put("messageCode", check.get("radomInt"));
			// return Message(SUCCESS, "验证码10分钟内有效", obj);
			return Message(SUCCESS, "验证码10分钟内有效", null);
		} catch (Exception e) {
			return LoggerUtil.logInfo(e, ERROR);
		} finally {
			jedis.close();
		}
	}
}
